/* 
 * File:   Server.cpp
 * Author: Lance
 * 
 * Created on September 29, 2012, 10:42 PM
 */

#include "Server.h"

Server::Server(int port, bool debug) {
	this->debug = debug;
	init(port);
	if(debug)
		threadPool.debug = true;
}

Server::Server(const Server& orig) {
}

Server::~Server() {
}
void Server::init(int port)
{
	this->port = port;
	clientlength = sizeof(client);
	initSocket();
	socketListen();
}

void Server::initSocket()
{
	// setup socket address structure
	memset(&server,0,sizeof(server));
	server.sin_family = AF_INET;
	server.sin_port = htons(port);
	server.sin_addr.s_addr = INADDR_ANY;

	socket_handle = socket(PF_INET,SOCK_STREAM,0);
	if (!socket)
	{
		perror("socket");
		exit(-1);
	}

	  // set socket to immediately reuse port when the application closes
	int opt = 1;
	if (setsockopt(socket_handle, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) < 0) {
		perror("setsockopt");
		exit(-1);
	}

	  // call bind to associate the socket with our local address and
	  // port
	if (bind(socket_handle,(const struct sockaddr *)&server,sizeof(server)) < 0) {
		perror("bind");
		exit(-1);
	}

	  // convert the socket to listen for incoming connections
	if (listen(socket_handle,SOMAXCONN) < 0) {
		perror("listen");
		exit(-1);
	}
}

void Server::socketListen() {
	while(1)
	{
		int client_connection;
		while ((client_connection = accept(socket_handle,(struct sockaddr *)&client,&clientlength)) > 0) {
			ClientHandler * handler = new ClientHandler(client_connection);
			if(debug)
				handler->debug = true;
			threadPool.enqueue(handler);
		}
	}
	close(socket_handle);
}

int main(int argc, char** argv) {
	int port = 3000;
	bool debug = false;
	int option;
	while ((option = getopt(argc,argv,"p:d:")) != -1)
	{
		switch (option)
		{
			case 'p':
				port = atoi(optarg);
				break;
			case 'd':
				debug = true;
				break;
			default:
				cout << option;
				cout << " is an invalid option" << endl;
				cout << "USAGE: msgd [-p port] [-d DEBUG]" << endl;
				exit(EXIT_FAILURE);
		}
	}
	Server messageServer(port, debug);
	return 0;
}